/*
 * Created on Feb 19, 2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package ModuleBuilder.UI.tree;

/*
 * This code is based on an example provided by Richard Stanford, 
 * a tutorial reader.
 */

import java.awt.GridLayout;
import java.awt.Toolkit;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.*;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;

public class DynamicTree extends JPanel {
    protected DefaultMutableTreeNode rootNode;
    protected DefaultTreeModel treeModel;
    protected JTree tree;
    private Toolkit toolkit = Toolkit.getDefaultToolkit();

    public DynamicTree() {
        super(new GridLayout(1,0));
        
        rootNode = new DefaultMutableTreeNode("Game Data");
        treeModel = new DefaultTreeModel(rootNode);
        treeModel.addTreeModelListener(new MyTreeModelListener());

        tree = new JTree(treeModel);
        tree.setEditable(false);	// do NOT allow node name to be ediable
        
        tree.getSelectionModel().setSelectionMode
                (TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.setShowsRootHandles(true);

        JScrollPane scrollPane = new JScrollPane(tree);
        add(scrollPane);
    }

    /** Remove all nodes except the root node. */
    public void clear() {
        rootNode.removeAllChildren();
        reload();
    }

	public void reload() {
		treeModel.reload();
	}
	
	public void nodeChanged( DefaultMutableTreeNode node ){
		treeModel.nodeChanged(node);
	}
	
	public DefaultMutableTreeNode getCurrentNode() {
		DefaultMutableTreeNode currentNode = null;
		TreePath currentSelection = tree.getSelectionPath();
		if (currentSelection != null) {
			currentNode = (DefaultMutableTreeNode)(currentSelection.getLastPathComponent());
		}
		return ( currentNode );
	}
	
    /** Remove the currently selected node. */
    public void removeCurrentNode() {
        TreePath currentSelection = tree.getSelectionPath();
        if (currentSelection != null) {
            DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
                         (currentSelection.getLastPathComponent());
            MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
            if (parent != null) {
                treeModel.removeNodeFromParent(currentNode);
                return;
            }
        } 

        // Either there was no selection, or the root was selected.
        toolkit.beep();
    }

    /** Add child to the currently selected node. */
    public DefaultMutableTreeNode addObject(Object child) {
        DefaultMutableTreeNode parentNode = null;
        TreePath parentPath = tree.getSelectionPath();

        if (parentPath == null) {
            parentNode = rootNode;
        } else {
            parentNode = (DefaultMutableTreeNode)
                         (parentPath.getLastPathComponent());
        }

        return addObject(parentNode, child, true);
    }

    public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
                                            Object child) {
        // return addObject(parent, child, false);
		return addObject(parent, child, true);
    }

    public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
                                            Object child, 
                                            boolean shouldBeVisible) {
        DefaultMutableTreeNode childNode = 
                new DefaultMutableTreeNode(child);

        if (parent == null) {
            parent = rootNode;
        }

        treeModel.insertNodeInto(childNode, parent, 
                                 parent.getChildCount());

        //Make sure the user can see the lovely new node.
        if (shouldBeVisible) {
            tree.scrollPathToVisible(new TreePath(childNode.getPath()));
        }
        return childNode;
    }

    public DefaultMutableTreeNode insertObject(DefaultMutableTreeNode parent,
            Object child, 
            boolean shouldBeVisible,
			int index) {
		DefaultMutableTreeNode childNode = 
		new DefaultMutableTreeNode(child);
		
		if (parent == null) {
			parent = rootNode;
		}
		
		treeModel.insertNodeInto(childNode, parent, index);
		
		//Make sure the user can see the lovely new node.
		if (shouldBeVisible) {
			tree.scrollPathToVisible(new TreePath(childNode.getPath()));
		}
		return childNode;
	}
		
    
	/**
	 * Will need to add under the grand parent of the child node
	 * 
	 * @param parent the node where the insertion is happening
	 * @param child the new node to be added
	 * @param shouldBeVisible should be set to true
	 * @return the new childNode
	 */
	public DefaultMutableTreeNode addSiblingObject(DefaultMutableTreeNode parent,
											Object child, 
											boolean shouldBeVisible) {
		DefaultMutableTreeNode childNode = 
				new DefaultMutableTreeNode(child);
		DefaultMutableTreeNode grandParent = null;
		if (parent == null) {
			parent = rootNode;
			grandParent = rootNode;
		}
	
		// first we need to find the path, the one right before the 
		// last item is the parent
		TreeNode[] path;		 
		path = treeModel.getPathToRoot(parent);
		int pathDepth = path.length;
		if ( pathDepth <= 1 ) {
			// this is the root, so set grandparent to root as well
			grandParent = rootNode;
		} else {
			grandParent = (DefaultMutableTreeNode)path[pathDepth-2];
		}
		
		treeModel.insertNodeInto(childNode, grandParent, grandParent.getChildCount());

		//Make sure the user can see the lovely new node.
		if (shouldBeVisible) {
			tree.scrollPathToVisible(new TreePath(childNode.getPath()));
		}
		return childNode;
	}


	public JTree getTree() {
		return ( tree );
	}
	
    class MyTreeModelListener implements TreeModelListener {
        public void treeNodesChanged(TreeModelEvent e) {
//            DefaultMutableTreeNode node;
//            node = (DefaultMutableTreeNode)
//                     (e.getTreePath().getLastPathComponent());
//
//            /*
//             * If the event lists children, then the changed
//             * node is the child of the node we've already
//             * gotten.  Otherwise, the changed node and the
//             * specified node are the same.
//             */
//            try {
//                int index = e.getChildIndices()[0];
//                node = (DefaultMutableTreeNode)
//                       (node.getChildAt(index));
//            } catch (NullPointerException exc) {}
//
//            System.out.println("The user has finished editing the node.");
//            System.out.println("New value: " + node.getUserObject());
        }
        public void treeNodesInserted(TreeModelEvent e) {
        }
        public void treeNodesRemoved(TreeModelEvent e) {
        }
        public void treeStructureChanged(TreeModelEvent e) {
        }
    }
	/**
	 * @return
	 */
	public DefaultMutableTreeNode getTreeRoot() {
		return ((DefaultMutableTreeNode)treeModel.getRoot());
	}
	
	public void setTreeRoot(DefaultMutableTreeNode rootIn) {
		treeModel.setRoot(rootIn);
		return;
	}

}


